﻿#ifndef _tcp_client_impl_20220407_
#define _tcp_client_impl_20220407_

#include <string>
#include <memory>
#include <atomic>
#include <mutex>
#include <SLT_tool_pub.h>

//event id
#define EPOLL_LIST_CMD_ADD_LISTEN_SOCKET        1
#define EPOLL_LIST_ADD_CONNECT                  3
#define EPOLL_LIST_SHUTDOWNFLG                  4
#define EPOLL_LIST_SOCKET_DEL                   6
#define EPOLL_LIST_SOCKET_STARTRECV             7
#define EPOLL_LIST_SOCKET_RECVDATAONE           8
#define EPOLL_LIST_SOCKET_CHECKTIMEOUT          9   //检测tcpclient超时

#define SHUTDOWNFLG                 1

#include "SL_tcpClient.h"

class SLTcpServerEpollImpl;
class SLTcpClientEpollImpl : public SLTcpClient, public std::enable_shared_from_this<SLTcpClientEpollImpl>,public SLT_memLeakCheck<SLTcpClientEpollImpl>
{
public:
    enum tcp_work_state
    {
        tcp_work_state_init,
        tcp_work_state_conning, //连接中
        tcp_work_state_ok
    };
public:
    SLTcpClientEpollImpl(uint32_t _id);
    ~SLTcpClientEpollImpl();

    virtual void bindCB(SLTcpClientCBPtr _pcb);
    virtual void connect2(std::string _serIp, int _serPort, int _timeout = 5000, std::string _lip = "", int _lport = 0);
    virtual void close2();
    virtual int  send2(const char* _pdata, int _dataLen);
    virtual void recv2();

    virtual void setRecv(bool _enable);
    virtual bool getRecv() { return m_brecv; }
    virtual int  getRecvCount() { return m_recvCount; }

    virtual const slIpAddr& getLocalAddr();
    virtual const slIpAddr& getRemoteAddr();
public:
    std::string toString();
public:
    int NetConnect(int port, const std::string& host, int timeOut);
    int NetWriteSocket(int nSocket, const char* writeBuf, int writeSize,bool _sendcache = false);
    int NetSetNoDelay(int nSocket);
    int NetSetSendTimeo(int nSocket, int _outMs);
    void NetClose(int socket);
    int NetReadSocketOne(int nSocket, char* readBuf, int readSize);

    void _close2();
    static void NoBlock(int fd);

    void onSend2Net();
    int onRecvFromNet();
    int onRecvFromNetInvoke(bool _deccount);

    void onSend();
    void onRecvData(char* _pdata, int _len);
    void onError(tcp_error_type _type);
    SLTcpClientCBPtr m_pcb;

    tcp_work_state   m_workState = tcp_work_state_init;  //被动连接时设置为成功
    int m_lip = 0;  //本地序
    int m_lport = 0;
    slIpAddr m_laddr;
    int m_rip = 0;
    int m_rport = 0;
    slIpAddr m_raddr;

    SLT_memBuf  m_sendBuf;    //发送缓存，一次发送保证全部发送成，again了。就缓存再发送

    int m_socket = -1;
    char m_recvBuf[1024];
    int  m_recvLen = 800;    //每次接收的最大长度,不能和buf 相等。接收时会在末尾补充0
    bool m_brecv = true;    //默认接收，在不接收的情况下，远端关闭事件也没有
    std::atomic<int>   m_recvCount; //在不接受模式下，投递的接收次数

    bool               m_isActive = true;
    SLT_elapseTimer    m_lastActiveTime; //最后活动时间。超过3分钟则回收

    std::mutex  m_socketLock;
    SLTcpServerEpollImpl* m_pserver = nullptr;

    uint32_t   m_clientID;

    //static std::atomic<uint32_t>   m_clientBaseID;
};
typedef std::shared_ptr<SLTcpClientEpollImpl>   SLTcpClientEpollImplPtr;

#endif